
/**
 * nobittercipher.h
 * 
 * NobitterCipher is a cipher to code a plain text to a tinyurl
 * 
 * Copyright (c) 2008 Harunobu Oyama <nobukichi at gmail.com>
 * Licensed under GNU GPL version 3
 *
 */

#ifndef		NOBITTER_CIPHER_INCLUDED
#define		NOBITTER_CIPHER_INCLUDED

#include	<map>
#include	<QObject>
#include	<QString>
#include	<QHttp>

/************************************************************************/
/*                                                                      */
/* NobitterCipher encrypt given string to a tinyurl in 4 steps          */
/*   1. Encrypt the given string with AES using the given key           */
/*   2. Base64-encode the encrypted byte stream                         */
/*   3. Attach the base 64 string to the baseUrl specified in the ctor  */
/*      The default baseUrl is http://code.google.com/p/nobitter/?dmy=  */
/*   4. TinyUrl-encode the long url given by step 3.                    */
/*                                                                      */
/* The decryption is done in the other way round.                       */
/*                                                                      */
/* As TinyUrl-encode/decode is done by tinyurl.com, both encryption and */
/*   decryption results are reported asynchronously by signals.         */
/*                                                                      */
/************************************************************************/

class TinyUrlAPI;

class NobitterCipher : public QObject
{
	Q_OBJECT
		
public:
	//! param baseUrl dummy url header ("http://code.google.com/p/nobitter/?dmy=")
	//! param key AES encryption key
	//! param parent parent of the cypher object, used for automatic deletion
	NobitterCipher(const QString& baseUrl, const QString& key, QObject* parent = 0);
	
	//! set AES encryption key
	void setKey(const QString& key);

	//! start nobitter encryption
	//! the result of this function will be asynchronously reported by signalEncrypted
	void encrypt(const QString& text);
	
	//! start nobitter decryption
	//! the result of this function will be asynchronously reported by signalDecrypted
	void decrypt(const QString& encryptedUrl);

	//! reset all the request before exiting.
	void reset();
	
signals:
	//! when a http error is detected, this signal will be emitted
	void signalDetectedHttpError(QHttp::Error error);

	//! when encrypt request completes, this singal will be emitted
	void signalEncrypted(const QString& text, const QString& encryptedUrl);

	//! when decrypt request completes, this signal will be emitted
	void signalDecrypted(const QString& encryptedUrl, const QString& text);
	
private:
	//! disallow copy/assign NobitterCipher instance
	NobitterCipher(const NobitterCipher&);
	NobitterCipher& operator=(const NobitterCipher&);

	TinyUrlAPI* pTinyUrlAPI;
	QString baseUrl;
	QString encryptionKey;

	//! cache to keep the pair of original url and the associated plain text
	std::map<QString, QString> originalUrlToPlainTextCache;

private slots:
	//! slot to receive http errors from pTinUrlAPI
	void slotReportHttpError(QHttp::Error error);
	//! slot to receive encrypted tinyurl from pTinUrlAPI
	void slotReportEncryptedUrl(const QString& orgUrl, const QString& tinyUrl);
	//! slot to receive decrypted url from pTinUrlAPI
	void slotReportDecryptedText(const QString& tinyUrl, const QString& orgUrl);
};

#endif	//	NOBITTER_CIPHER_INCLUDED

